from app.schemas.work_order import *

import requests
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Image, PageBreak
from reportlab.lib.units import cm
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
from reportlab.lib import colors
from PIL import Image as PILImage
from io import BytesIO
from utils.request import Request
from utils.upload import oss_upload
from loguru import logger

def report(work_order_detail: WorkOrderReport):
    # Register font from JSON input
    register_fonts('assets/fonts/MSYH.ttf')
    # Create PDF file, top margin set to 1 cm
    buffer = BytesIO()
    pdf = SimpleDocTemplate(buffer, pagesize=A4, topMargin=1 * cm, bottomMargin=1 * cm)
    # 主页和内页
    main_table_element = create_main_page(work_order_detail)
    pdf_elements = [main_table_element, PageBreak()]
    sub_table_elements = create_sub_page(work_order_detail)
    if sub_table_elements:
        for sub_table in sub_table_elements:
            pdf_elements.append(sub_table)
    # Build PDF
    pdf.build(pdf_elements)
    pdf_data = buffer.getvalue()
    buffer.close()
    upload_work_order_report(pdf_data, work_order_detail)


# Register the font
def register_fonts(font_path):
    pdfmetrics.registerFont(TTFont('MicrosoftYaHei', font_path))


# Resize image
def resize_image(image_url, target_width_cm):
    response = requests.get(image_url, verify=False)
    response.raise_for_status()  # 确保请求成功
    img = PILImage.open(BytesIO(response.content))
    aspect_ratio = img.height / img.width
    # 计算目标宽度和高度
    if img.width > img.height:
        target_height_cm = target_width_cm * aspect_ratio
        target_width = target_width_cm * cm
        target_height = target_width * aspect_ratio
    else:
        target_height_cm = target_width_cm
        target_width_cm = target_height_cm / aspect_ratio
        target_width = target_width_cm * cm
        target_height = target_height_cm * cm

    # 创建 ReportLab 的 Image 对象
    return Image(BytesIO(response.content), width=target_width, height=target_height)


def create_main_page(detail: WorkOrderReport):
    if detail.node_list:
        misstake = False
        for node in detail.node_list:
            if node.audit_result and '误报审核通过' in node.audit_result:
                misstake = True
    main_table_data = [
        ["无人机巡检工单记录"],
        ["工单标题", detail.title, "", "", "是否完结", "是" if detail.status == 50 else "否"],
        ["创建时间", detail.create_time, "工单类型", "一般工单", "是否误报", "是" if misstake else "否"],
        ["事件类型", detail.event_defect.event_target_text, "发起人", detail.apply_staff_name, "处理人", detail.process_staff_name],
        ["目标数量", detail.event_defect.target_num, "缺陷等级", detail.event_defect.level_text, "缺陷位置", detail.event_defect.location],
        ["缺陷说明:\n" + detail.remark]
    ]
    img_list = [[], []]
    for index, img_path in enumerate(detail.media_file_urls):
        resized_image = resize_image(img_path, 8.5)
        img_index = 0
        if (index >= 4):
            break
        elif (index >= 2):
            img_index = 1
        img_list[img_index].append(resized_image)  # Insert image at the correct position
        img_list[img_index].append(None)
        img_list[img_index].append(None)
    for img_arr in img_list:
        main_table_data.append(img_arr)
    # Define table styles
    row_heights = [None, 1 * cm, 1 * cm, 1 * cm, 1 * cm, 3 * cm, 9 * cm, 9 * cm]
    main_table_element = Table(main_table_data, colWidths=[2*cm, 4*cm, 2*cm, 4*cm, 2*cm, 4*cm], rowHeights=row_heights)
    main_table_element.setStyle(TableStyle([
        ('SPAN', (0, 0), (-1, 0)),  # 合并第一行所有列
        ('LEADING', (0, 0), (-1, 0), 22), # 设置第一行的行高为22
        ('ALIGN', (0, 0), (-1, 0), 'CENTER'), # 第一行文字居中
        ('FONTSIZE', (0, 0), (-1, 0), 18), # 第一行文字字号18
        ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#E1EFD9')), # 第一行为表头 背景色为浅绿
        ('SPAN', (1, 1), (3, 1)),  # 合并第2行2 3 4列
        ('SPAN', (0, 5), (-1, 5)),  # 合并第8行所有列 用于显示说明
        ('LEADING', (0, 5), (-1, 5), 15), # 说明部分 行高
        ('SPAN', (0, 6), (2, 6)),  # 合并第7行2 3 4列
        ('SPAN', (3, 6), (5, 6)),  # 合并第7行2 3 4列
        ('SPAN', (0, 7), (2, 7)),  # 合并第7行2 3 4列
        ('SPAN', (3, 7), (5, 7)),  # 合并第7行2 3 4列
        ('ALIGN', (0, 6), (-1, 6), 'CENTER'), # 图片显示居中
        ('BACKGROUND', (1, 1), (-1, -1), colors.white), # 除了第1行其他的背景都为白色
        ('TEXTCOLOR', (0, 0), (-1, -1), colors.black), # 所有的字的颜色为黑色
        ('LEADING', (0, 1), (-1, 3), 13), # 除了第1行至第4行 行高为12
        ('ALIGN', (0, 1), (-1, 4), 'LEFT'), # 除了第1行 他行的行为左对齐
        ('ALIGN', (0, 6), (-1, -1), 'LEFT'), # 除了第1行 他行的行为左对齐
        ('VALIGN', (0, 0), (-1, 4), 'MIDDLE'), # 所有行高度居中
        ('VALIGN', (0, 5), (-1, 7), 'TOP'), # 所有行高度居中
        ('ALIGN', (3, 6), (5, 6), 'RIGHT'), # 除了第1行 他行的行为左对齐
        ('ALIGN', (3, 7), (5, 7), 'RIGHT'), # 除了第1行 他行的行为左对齐
        ('FONTNAME', (0, 0), (-1, -1), 'MicrosoftYaHei'), # 所有字体为微软雅黑
        ('GRID', (0, 0), (-1, 5), 1, colors.black), # 绘制所有框线
        ('LINEBELOW', (0, 7), (-1, 7), 1, colors.black), # 为图片行设置下边框
        ('LINEBEFORE', (0, 6), (0, 7), 1, colors.black), # 给图片行设置左边框线
        ('LINEAFTER', (-1, 6), (-1, 7), 1, colors.black), # 给图片行设置右边框线
        ('LEFTPADDING', (0, 0), (-1, -1), 5), # 所有行左侧留白5
        ('BOTTOMPADDING', (0, 0), (-1, -1), 5), # 所有行底部留白5
        ('TOPPADDING', (0, 0), (-1, -1), 5), # 所有行顶侧留白5
        ('FONTSIZE', (0, 1), (-1, -1), 10), # 除了第1行其他的字号为10
    ]))
    return main_table_element


def create_sub_page(detail: WorkOrderReport):
    sub_table_page = []
    for node in detail.node_list:
        if '未处理' in node.action_text:
            continue
        if not '复核' in node.action_text and not '处理' in node.action_text:
            continue
        if not node.pic_list:
            continue
        img_list = [[], []]
        for index, img_path in enumerate(node.pic_list):
            resized_image = resize_image(img_path, 8.5)
            img_index = 0
            if (index >= 2):
                img_index = 1
            img_list[img_index].append(resized_image)  # Insert image at the correct position
            img_list[img_index].append(None)
        # Copy the element to modify it
        audit_text = "\n审核意见:\n" + node.audit_remark if node.audit_result and node.audit_remark else ""
        sub_element = [
            ["无人机巡检工单记录"],
            ["操作节点", node.action_text, "处理时间", node.origin_operate_time],
            ["处理人", node.operate_staff_name, "审核时间", node.operate_time if node.audit_result else '--'],
            ["现场情况说明:\n" + node.remark if node.remark else "" + audit_text]
        ]
        for img_arr in img_list:
            sub_element.append(img_arr)
        sub_table = Table(
            sub_element,
            colWidths=[3 * cm, 6 * cm, 3 * cm, 6 * cm],
            rowHeights=[None, 1 * cm, 1 * cm, 4 * cm, 9 * cm, 9 * cm])
        sub_table.setStyle(
            TableStyle([
                ('SPAN', (0, 0), (-1, 0)),  # 合并第一行所有列
                ('LEADING', (0, 0), (-1, 0), 22),  # 设置第一行的行高为22
                ('ALIGN', (0, 0), (-1, 0), 'CENTER'),  # 第一行文字居中
                ('FONTSIZE', (0, 0), (-1, 0), 18),  # 第一行文字字号18
                ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#E1EFD9')),  # 第一行为表头 背景色为浅绿
                ('SPAN', (0, 3), (-1, 3)),  # 合并第6行所有列 用于显示说明
                ('LEADING', (0, 3), (-1, 3), 15), # 说明部分 行高为
                ('SPAN', (0, 4), (1, 4)),  # 合并第7行2 3 4列
                ('SPAN', (2, 4), (3, 4)),  # 合并第7行2 3 4列
                ('SPAN', (0, 5), (1, 5)),  # 合并第7行2 3 4列
                ('SPAN', (2, 5), (3, 5)),  # 合并第7行2 3 4列
                ('ALIGN', (0, 4), (-1, 5), 'CENTER'),  # 图片显示居中
                ('BACKGROUND', (1, 1), (-1, -1), colors.white), # 除了第1行其他的背景都为白色
                ('TEXTCOLOR', (0, 0), (-1, -1), colors.black), # 所有的字的颜色为黑色
                ('LEADING', (0, 1), (-1, 3), 13), # 除了第1行至第4行 行高为12
                ('ALIGN', (0, 1), (-1, 3), 'LEFT'), # 除了第1行 他行的行为左对齐
                ('VALIGN', (0, 0), (-1, 2), 'MIDDLE'), # 所有行高度居中
                ('VALIGN', (0, 3), (-1, 3), 'TOP'), # 所有行高度居中
                ('VALIGN', (0, 4), (-1, 5), 'MIDDLE'), # 所有行高度居中
                ('FONTNAME', (0, 0), (-1, -1), 'MicrosoftYaHei'), # 所有字体为微软雅黑
                ('GRID', (0, 0), (-1, 3), 1, colors.black), # 绘制所有框线
                ('LINEBELOW', (0, 5), (-1, 5), 1, colors.black), # 为图片行设置下边框
                ('LINEBEFORE', (0, 4), (0, 5), 1, colors.black), # 给图片行设置左边框线
                ('LINEAFTER', (-1, 4), (-1, 5), 1, colors.black), # 给图片行设置右边框线
                ('LEFTPADDING', (0, 0), (-1, -1), 5), # 所有行左侧留白5
                ('BOTTOMPADDING', (0, 0), (-1, -1), 5), # 所有行底部留白5
                ('TOPPADDING', (0, 0), (-1, -1), 5), # 所有行顶侧留白5
                ('FONTSIZE', (0, 1), (-1, -1), 10), # 除了第1行其他的字号为10
            ]))
        sub_table_page.append(sub_table)

        # 添加分页符（除最后一个表格外）
        if node != detail.node_list[-1]:
            sub_table_page.append(PageBreak())
    return sub_table_page


def upload_work_order_report(pdf_data, report: WorkOrderReport):
    upload = oss_upload(report.oss_config)
    data = None
    res = upload(f'{report.id}.pdf', pdf_data)
    if res:
        object_key = res
        data = {'sourceId': report.id, 'objectKey': object_key}
        logger.info(f"[work_order_report]上传oss成功")
        Request.callback_result(data, url=report.upload_callback_url)